package com.lktx.sso.admin.service;

import cn.hserver.core.ioc.annotation.Autowired;
import cn.hserver.core.ioc.annotation.Bean;
import cn.hserver.core.ioc.annotation.Value;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.lktx.sso.admin.entity.*;
import com.lktx.sso.admin.mapper.*;
import com.lktx.sso.admin.vo.SsoUserApp;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;

import javax.security.auth.login.LoginException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * SSO用户表 服务类
 */
@Slf4j
@Bean
public class SsoUserService {

    @Autowired
    private SsoUserMapper mapper;

    @Autowired
    private SsoAppService ssoAppService;

    @Autowired
    private SsoAppAccessPolicyService ssoAppAccessPolicyService;

    @Autowired
    private SsoUserJobMapper ssoUserJobMapper;

    @Autowired
    private SsoAppOidcConfigMapper ssoAppOidcConfigMapper;

    @Autowired
    private SsoAppJwtConfigMapper ssoAppJwtConfigMapper;

    @Value("oauth.baseIss")
    private String baseUrl;

    /**
     * 分页查询列表
     *
     * @param page   分页对象
     * @param entity 查询实体
     * @return 所有数据
     */
    public Page<SsoUser> page(Page<SsoUser> page, SsoUser entity, List<Integer> organizationIds) {
        return mapper.paginateWithRelations(page, new QueryWrapper()
                .in(SsoUser::getSsoOrganizationId, organizationIds, organizationIds != null && !organizationIds.isEmpty())
                .like(SsoUser::getPhone, entity.getPhone(), StrUtil.isNotEmpty(entity.getPhone()))
                .like(SsoUser::getPassword, entity.getPassword(), StrUtil.isNotEmpty(entity.getPassword()))
                .like(SsoUser::getName, entity.getName(), StrUtil.isNotEmpty(entity.getName()))
                .like(SsoUser::getNickname, entity.getNickname(), StrUtil.isNotEmpty(entity.getNickname()))
                .like(SsoUser::getAvatar, entity.getAvatar(), StrUtil.isNotEmpty(entity.getAvatar()))
                .like(SsoUser::getSource, entity.getSource(), StrUtil.isNotEmpty(entity.getSource()))
                .like(SsoUser::getRemark, entity.getRemark(), StrUtil.isNotEmpty(entity.getRemark()))
                .like(SsoUser::getEmail, entity.getEmail(), StrUtil.isNotEmpty(entity.getEmail()))
                .like(SsoUser::getUsername, entity.getUsername(), StrUtil.isNotEmpty(entity.getUsername()))
                .orderBy(SsoUser::getSsoUserId, false)
        );
    }

    /**
     * 不分页查询列表
     *
     * @param entity 实体对象
     * @return 查询结果
     */
    public List<SsoUser> list(SsoUser entity) {
        return mapper.selectListByQuery(new QueryWrapper()
                .like(SsoUser::getPhone, entity.getPhone(), StrUtil.isNotEmpty(entity.getPhone()))
                .like(SsoUser::getPassword, entity.getPassword(), StrUtil.isNotEmpty(entity.getPassword()))
                .like(SsoUser::getName, entity.getName(), StrUtil.isNotEmpty(entity.getName()))
                .like(SsoUser::getNickname, entity.getNickname(), StrUtil.isNotEmpty(entity.getNickname()))
                .like(SsoUser::getAvatar, entity.getAvatar(), StrUtil.isNotEmpty(entity.getAvatar()))
                .like(SsoUser::getSource, entity.getSource(), StrUtil.isNotEmpty(entity.getSource()))
                .like(SsoUser::getRemark, entity.getRemark(), StrUtil.isNotEmpty(entity.getRemark()))
                .like(SsoUser::getEmail, entity.getEmail(), StrUtil.isNotEmpty(entity.getEmail()))
                .like(SsoUser::getUsername, entity.getUsername(), StrUtil.isNotEmpty(entity.getUsername()))
                .orderBy(SsoUser::getSsoUserId, false)
        );
    }

    public List<SsoUser> listKeyword(String keyword) {
        return mapper.selectListByQuery(new QueryWrapper().eq(SsoUser::getLocked, 0).and(k -> {
                            k.or(r -> {
                                r.like(SsoUser::getPhone, keyword, StrUtil.isNotEmpty(keyword));
                            });
                            k.or(r -> {
                                r.like(SsoUser::getUsername, keyword, StrUtil.isNotEmpty(keyword));
                            });
                            k.or(r -> {
                                r.like(SsoUser::getName, keyword, StrUtil.isNotEmpty(keyword));
                            });
                            k.or(r -> {
                                r.like(SsoUser::getNickname, keyword, StrUtil.isNotEmpty(keyword));
                            });
                            k.or(r -> {
                                r.like(SsoUser::getEmail, keyword, StrUtil.isNotEmpty(keyword));
                            });
                            k.or(r -> {
                                r.like(SsoUser::getRemark, keyword, StrUtil.isNotEmpty(keyword));
                            });
                        })
                        .orderBy(SsoUser::getSsoUserId, false).limit(20)
        );
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    public SsoUser getById(Integer id) {
        return mapper.selectOneById(id);
    }


    /**
     * 新增单条数据
     *
     * @param entity 实体对象
     */
    public void save(SsoUser entity) {
        mapper.insert(entity);
        if (!entity.getJobIds().isEmpty()) {
            List<SsoUserJob> list = entity.getJobIds().stream().map(k -> {
                SsoUserJob ssoUserJob = new SsoUserJob();
                ssoUserJob.setUserId(entity.getSsoUserId());
                ssoUserJob.setJobId(k);
                return ssoUserJob;
            }).toList();
            ssoUserJobMapper.insertBatch(list);
        }
    }

    /**
     * 修改单条数据
     *
     * @param entity 实体对象
     */
    public void update(SsoUser entity) {
        mapper.update(entity);
        ssoUserJobMapper.deleteByQuery(new QueryWrapper().eq(SsoUserJob::getUserId,entity.getSsoUserId()));
        if (!entity.getJobIds().isEmpty()) {
            List<SsoUserJob> list = entity.getJobIds().stream().map(k -> {
                SsoUserJob ssoUserJob = new SsoUserJob();
                ssoUserJob.setUserId(entity.getSsoUserId());
                ssoUserJob.setJobId(k);
                return ssoUserJob;
            }).toList();
            ssoUserJobMapper.insertBatch(list);
        }
    }

    /**
     * 批量删除数据
     *
     * @param ids 主键集合
     */
    public void deleteByIds(List<Integer> ids) {
        mapper.deleteBatchByIds(ids);
    }

    /**
     * 登录
     * @param account
     * @param password
     * @return
     */
    public SsoUser login(String account, String password,String clientId) throws LoginException {
        if (clientId == null) {
            return null;
        }

        SsoUser ssoUser = mapper.selectOneByQuery(
                new QueryWrapper().eq(SsoUser::getLocked, 0).eq(SsoUser::getPassword, password).and(k -> {
                    k.or(r -> {
                        r.eq(SsoUser::getNickname, account);
                    });
                    k.or(r -> {
                        r.eq(SsoUser::getUsername, account);
                    });
                    k.or(r -> {
                        r.eq(SsoUser::getEmail, account);
                    });
                    k.or(r -> {
                        r.eq(SsoUser::getPhone, account);
                    });
                    k.or(r -> {
                        r.eq(SsoUser::getName, account);
                    });
                })
        );
        if (ssoUser == null) {
            return null;
        }

        //检查应用权限
        SsoApp byClientId = ssoAppService.getByClientId(clientId);
        if (byClientId == null) {
            return null;
        }

        //检查用户级
        boolean b = ssoAppAccessPolicyService.checkByUserIdAccess(byClientId.getSsoAppId(), ssoUser.getSsoUserId());
        if (b) {
            return ssoUser;
        }
        //检查用户组
        b=ssoAppAccessPolicyService.checkByUserGroupAccess(byClientId.getSsoAppId(), ssoUser.getSsoUserId());
        if (b) {
            return ssoUser;
        }
        //检查组织级别
        b = ssoAppAccessPolicyService.checkByOrganizationAccess(byClientId.getSsoAppId(), ssoUser.getSsoOrganizationId());
        if (b){
            return ssoUser;
        }
        throw new LoginException("暂无登录权限");
    }


    public SsoUserApp login(String ssoUserId) throws LoginException {
        SsoUser ssoUser = mapper.selectOneByQuery(
                new QueryWrapper().eq(SsoUser::getLocked, 0).eq(SsoUser::getSsoUserId, ssoUserId)
        );
        if (ssoUser == null) {
            return null;
        }
        //获取拥有的权限的应用程序
        //用户的用户组ID
        List<SsoApp> appByUser = ssoAppService.getAppByUser(ssoUser);
        return new SsoUserApp(ssoUser, appByUser);
    }


}